/**
 * Copyright 2019-2020 Huawei Technologies Co., Ltd
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef FUSION_ENGINE_UTILS_COMMON_CONSTANTS_DEFINE_H_
#define FUSION_ENGINE_UTILS_COMMON_CONSTANTS_DEFINE_H_

#include <map>
#include <string>
#include <vector>
#include "common/aicore_util_attr_define.h"
#include "common/aicore_util_types.h"
#include "common/aicore_util_constants.h"

namespace fe {
static const std::string ATTR_NAME_L2CACHE_GRAPH_READ_MODE = "_fe_l2cache_graph_read_mode";
static const std::string ATTR_NAME_SUPPORT_DYNAMIC_SHAPE = "support_dynamicshape";
static const std::string ATTR_NAME_ATOMIC_CLEAN_NODE_PTR = "atomic_clean_node_ptr";
static const std::string ATTR_NAME_INPUT_IS_VAR = "INPUT_IS_VAR";
static const std::string ATTR_NAME_OUTPUT_IS_VAR = "OUTPUT_IS_VAR";
static const std::string ATTR_NAME_NO_REUSE_MEM_FLAG = "no_reuse_mem_flag";

// op type
static const std::string OP_TYPE_DATA = "Data";
static const std::string OP_TYPE_ANN_DATA = "AnnData";
static const std::string OP_TYPE_AIPP_DATA = "AippData";
static const std::string OP_TYPE_CONST = "Const";
static const std::string OP_TYPE_CONSTANT = "Constant";
static const std::string OP_TYPE_VARIABLE = "Variable";

static const std::string OP_TYPE_ROIPOOLING = "ROIPooling";
static const std::string OP_TYPE_SSD_DETECTION_OUTPUT = "SSDDetectionOutput";

// config key in fe.ini
static const std::string CONFIG_KEY_ROOT = "rootdir";
static const std::string CONFIG_KEY_CUSTOM_PASS_FILE = "fusionpassmgr.aicore.custompasspath";
static const std::string CONFIG_KEY_BUILTIN_PASS_FILE = "fusionpassmgr.aicore.graphpasspath";
static const std::string CONFIG_KEY_GRAPH_FILE = "fusionrulemgr.aicore.graphfilepath";
static const std::string CONFIG_KEY_CUSTOM_FILE = "fusionrulemgr.aicore.customfilepath";
static const std::string CONFIG_KEY_ORIGINAL_NODES_ENABLE = "dump.originalnodes.enable";
static const std::string CONFIG_KEY_MAY_DUPLICATE_IN_AUTO_FUSION = "may.duplicate.in.autofusion";
static const std::string VECTOR_CORE_CONFIG_KEY_CUSTOM_PASS_FILE = "fusionpassmgr.vectorcore.custompasspath";
static const std::string VECTOR_CORE_CONFIG_KEY_BUILTIN_PASS_FILE = "fusionpassmgr.vectorcore.graphpasspath";
static const std::string VECTOR_CORE_CONFIG_KEY_GRAPH_FILE = "fusionrulemgr.vectorcore.graphfilepath";
static const std::string VECTOR_CORE_CONFIG_KEY_CUSTOM_FILE = "fusionrulemgr.vectorcore.customfilepath";
static const std::string FUSION_CONFIG_BUILT_IN_FILE = "fusion.config.built-in.file";

// constants value
static const int32_t PRIORITY_START_NUM = 0;
static const uint32_t MAX_L2_DATANUM = 8;
static const int32_t OP_STORE_FORMAT_SIZE = 6;  // The size of opstore config items in fe.ini file

static const int32_t DATA_VISIT_DIST_THRESHOLD = 5; // data distance threshlod for rc cache optimization
enum L2CacheReadMode { RM_NONE = -1, READ_LAST = 1, READ_INVALID = 2, NOT_NEED_WRITEBACK = 3 };

const std::map<L2CacheReadMode, std::string> L2CACHE_READ_MODE_STRING_MAP{{RM_NONE, "None"},
                                                                          {READ_LAST, "Read Last"},
                                                                          {READ_INVALID, "Read Invalid"},
                                                                          {NOT_NEED_WRITEBACK, "Not Need Writeback"}};

// The index of opstre config item in fe.ini file
enum OpStoreInfoIndex {
  IDX_PRIORITY = 0,     // priority index
  IDX_OPIMPL_TYPE,      // op_impl_type index
  IDX_CFG_FILEPATH,     // cfg_file_path index
  IDX_OPIMPL_FILEPATH,  // op_impl_file_path index
  IDX_NEED_PRECOMPILE,  // need precompile
  IDX_NEED_COMPILE,      // need compile
  IDX_BOTTOM
};

const std::map<std::string, bool> GE_SWITCH_MAP{ {"1", true}, {"0", false} };
const std::map<std::string, bool> GE_DISABLE_REUSE_MEMORY_MAP{{"1", false}, {"0", true}};
/* List of all precision mode */
static const std::vector<std::string> PRECISION_MODE_LIST = {ALLOW_MIX_PRECISION, FORCE_FP16, FORCE_FP32,
                                                             ALLOW_FP32_TO_FP16, MUST_KEEP_ORIGIN_DTYPE};

const char ASCEND_OPP_PATH[] = "ASCEND_OPP_PATH";
static const std::string OP_STOREINFO_PREFIX = "op.store.";
static const std::string NEED_PRECOMPILE_TRUE = "true";
static const std::string NEED_COMPILE_TRUE = "true";
static const std::map<std::string, BufferOptimize> BUFFER_OPTIMIZE_MAP{
        {OFF_OPTIMIZE, EN_OFF_OPTIMIZE}, {L1_OPTIMIZE, EN_L1_OPTIMIZE}, {L2_OPTIMIZE, EN_L2_OPTIMIZE}};

static const std::map<BufferOptimize, std::string> BUFFER_OPTIMIZE_STR_MAP{
        {EN_OFF_OPTIMIZE, OFF_OPTIMIZE}, {EN_L1_OPTIMIZE, L1_OPTIMIZE}, {EN_L2_OPTIMIZE, L2_OPTIMIZE}};

static const std::string BUFFER_OPTIMIZE_UNKNOWN = "unknown-buffer-optimize";
static const std::string BUFFER_FUSION_MODE_UNKNOWN = "unknown-buffer-fusion-mode";

const std::map<BufferOptimize, std::string> BUFFER_OPTIMIZE_STRING_MAP{
        {EN_UNKNOWN_OPTIMIZE, "unknown_optimize"},
        {EN_OFF_OPTIMIZE, "off_optimize"},
        {EN_L1_OPTIMIZE, "l1_optimize"},
        {EN_L2_OPTIMIZE, "l2_optimize"}
};

const std::map<BufferFusionMode, std::string> BUFFER_FUSION_MODE_STRING_MAP{
    {EN_OPTIMIZE_DISABLE, "optimize_disable"},
    {EN_L2_BUFFER, "l2_buffer"},
    {EN_L2_FUSION, "l2_fusion"},
};

const std::map<AppendArgsMode, std::string> APPEND_ARGS_MODE_STRING_MAP{
    {NO_ARGS, "no-append-args"},
    {L2_BUFFER_ARGS, "L2-buffer-append-args"},
    {L2_CACHE_ARGS, "L2-cache-append-args"}
};

const std::map<OpPattern, std::string> OP_PATTERN_STRING_MAP{{OP_PATTERN_OP_KERNEL, "kernel"},
                                                             {OP_PATTERN_FORMAT_AGNOSTIC, "formatAgnostic"},
                                                             {OP_PATTERN_BROADCAST, "broadcast"},
                                                             {OP_PATTERN_REDUCE, "reduce"},
                                                             {OP_PATTERN_OP_CUSTOMIZE, "dynamic"}};

const std::map<PrecisionPolicy, std::string> PRECISION_POLICY_STRING_MAP{
        {WHITE, "white-list"}, {BLACK, "black-list"}, {GRAY, "gray-list"}};

static const std::map<std::string, ge::DataType> STR_DTYPE_MAP{{"float", ge::DT_FLOAT},
                                                               {"float32", ge::DT_FLOAT},
                                                               {"float16", ge::DT_FLOAT16},
                                                               {"int8", ge::DT_INT8},
                                                               {"int16", ge::DT_INT16},
                                                               {"int32", ge::DT_INT32},
                                                               {"int64", ge::DT_INT64},
                                                               {"uint8", ge::DT_UINT8},
                                                               {"uint16", ge::DT_UINT16},
                                                               {"uint32", ge::DT_UINT32},
                                                               {"uint64", ge::DT_UINT64},
                                                               {"bool", ge::DT_BOOL},
                                                               {"double", ge::DT_DOUBLE},
                                                               {"dual", ge::DT_DUAL},
                                                               {"dual_sub_int8", ge::DT_DUAL_SUB_INT8},
                                                               {"dual_sub_uint8", ge::DT_DUAL_SUB_UINT8}};

// The config keys below in the configuration file is mandatory.
static const std::vector<std::string> MANDATORY_CONFIG_ITEMS{};

// The default value for the keys which is not configured in the files.
static const std::map<std::string, std::string> DEFAULT_CONFIG_ITEM_VALUE{};

// maps soc_version to ISA arch VERSION
static const std::map<std::string, ISAArchVersion> SOC_ISA_ARCH_VERSION_MAP{
        {SOC_VERSION_ASCEND610, EN_ISA_ARCH_V200},     {SOC_VERSION_ASCEND615, EN_ISA_ARCH_V200},
        {SOC_VERSION_ASCEND710, EN_ISA_ARCH_V200},     {SOC_VERSION_ASCEND710P, EN_ISA_ARCH_V200},
        {SOC_VERSION_ASCEND310, EN_ISA_ARCH_V100},     {SOC_VERSION_ASCEND910PREMIUMA, EN_ISA_ARCH_V100},
        {SOC_VERSION_ASCEND910A, EN_ISA_ARCH_V100},    {SOC_VERSION_ASCEND910B, EN_ISA_ARCH_V100},
        {SOC_VERSION_ASCEND910PROA, EN_ISA_ARCH_V100}, {SOC_VERSION_ASCEND910PROB, EN_ISA_ARCH_V100},
        {SOC_VERSION_HI3796CV300ES, EN_ISA_ARCH_V100}, {SOC_VERSION_HI3796CV300CS, EN_ISA_ARCH_V200},
        {SOC_VERSION_ASCEND920A, EN_ISA_ARCH_V210},    {SOC_VERSION_SD3403, EN_ISA_ARCH_V200}};

static const std::string OPS_SUBPATH_ASCEND910 = "ascend910";
static const std::string OPS_SUBPATH_ASCEND920 = "ascend920";
static const std::string OPS_SUBPATH_ASCEND710 = "ascend710";

static const std::map<std::string, std::string> SOC_OPS_SUBPATH_MAP {
        {SOC_VERSION_ASCEND910A, OPS_SUBPATH_ASCEND910}, {SOC_VERSION_ASCEND910B, OPS_SUBPATH_ASCEND910},
        {SOC_VERSION_ASCEND910PROA, OPS_SUBPATH_ASCEND910}, {SOC_VERSION_ASCEND910PROB, OPS_SUBPATH_ASCEND910},
        {SOC_VERSION_ASCEND910PREMIUMA, OPS_SUBPATH_ASCEND910}, {SOC_VERSION_ASCEND920A, OPS_SUBPATH_ASCEND920},
        {SOC_VERSION_ASCEND710P, OPS_SUBPATH_ASCEND710}};

}
#endif  // FUSION_ENGINE_UTILS_COMMON_CONSTANTS_DEFINE_H_